# encoding: UTF-8

"""
这里的是一个最简单的策略实现，并未考虑太多实盘中的交易细节，如：
1. 委托价格超出涨跌停价导致的委托失败
2. 委托未成交，需要撤单后重新委托
3. 断网后恢复交易状态
4. 等等
这些点是作者选择特意忽略不去实现，因此想实盘的朋友请自己多多研究CTA交易的一些细节，
做到了然于胸后再去交易，对自己的money和时间负责。
也希望社区能做出一个解决了以上潜在风险的Demo出来。
"""


from base.ctaBase import *
from strategy.ctaTemplate import CtaTemplate

########################################################################
class CondictionStrategy(CtaTemplate):
    """条件优化策略策略"""
    className = 'Condiction'
    author = u'何雨'

    initDays = 0
    hisBarOpen = []
    hisBarClose = []
    hisBarHigh = []
    hisBarLow = []

    currTime = ""
    currHour= ""


    #信号条件列表
    condictions = []
    #----------------------------------------------------------------------
    def __init__(self, ctaEngine, setting):
        """Constructor"""
        super(CondictionStrategy, self).__init__(ctaEngine, setting)
        
    #----------------------------------------------------------------------
    def onInit(self):
        """初始化策略（必须由用户继承实现）"""
        self.writeCtaLog(u'Condiction策略初始化')
        if self.ctaEngine.mode == self.ctaEngine.BAR_MODE: 
            initData = self.loadBar(self.initDays)
            
            for bar in initData:
                self.onBar(bar)
        else:
            initData = self.loadTick(self.initDays)
            for tick in initData:
                self.onTick(tick)
        
        self.putEvent()
        
    #----------------------------------------------------------------------
    def onStart(self):
        """启动策略（必须由用户继承实现）"""
        self.writeCtaLog(u'Condiction策略启动')
        self.putEvent()
    
    #----------------------------------------------------------------------
    def onStop(self):
        """停止策略（必须由用户继承实现）"""
        self.writeCtaLog(u'Condiction策略停止')
        self.putEvent()
    
    def addCondiction(self, signCondiction):
        """增加交易条件"""
        self.condictions.append(signCondiction)
        signCondiction.setStrategy(self)
        signCondiction.hisBar = self.hisBar
        signCondiction.hisBarOpen = self.hisBarOpen
        signCondiction.hisBarClose = self.hisBarClose
        signCondiction.hisBarHigh = self.hisBarHigh
        signCondiction.hisBarLow = self.hisBarLow


    #----------------------------------------------------------------------
    def onBar(self, bar):
        """收到Bar推送（必须由用户继承实现）"""

        #记录历史数据
        #self.hisBarClose.append(bar.close)
        #self.hisBarHigh.append(bar.high)
        #self.hisBarOpen.append(bar.open)
        #self.hisBarLow.append(bar.low)
        #print bar 
        #print self.period
        if not self.trading or (len(self.condictions) == 0):
            return
        for con in self.condictions:
            con.caculate()

        # self.outputSignal()
        #买入开仓
        buy = True
        for con in [condiction.buy() for condiction in self.condictions]:
            buy = buy and con
        #卖出平仓
        sell = True
        for con in [condiction.sell() for condiction in self.condictions]:
            sell = sell or con
        #卖出开仓
        short = True
        for con in [condiction.short() for condiction in self.condictions]:
            short = short and con
        #买入平仓
        cover = True
        for con in [condiction.cover() for condiction in self.condictions]:
            cover = cover or con

        if buy and self.ctaEngine.isFinishedOrders() and (self.getTotalPosition() == 0):
            self.outputSignal()
            print "Trade : buy 1"
            self.buy(bar.close, 1)
            
        if sell and self.ctaEngine.isFinishedOrders() and (self.getTotalPosition() != 0) and (self.getLongPosition() !=0):
            self.outputSignal()
            print "Trade : Sell 1"
            self.sell(bar.close, 1)
        if short and self.ctaEngine.isFinishedOrders() and (self.getTotalPosition() == 0):
            self.outputSignal()
            print "Trade : short 1"
            self.short(bar.close, 1)
        if cover and self.ctaEngine.isFinishedOrders() and (self.getTotalPosition() !=0) and (self.getShortPosition() !=0):
            self.outputSignal()
            print "Trade : cover 1"
            self.cover(bar.close, 1)

        #打印信号状态
        #print buy, sell, short, cover
        # 发出状态更新事件
        self.putEvent()
        
    #----------------------------------------------------------------------
    def onOrder(self, order):
        """收到委托变化推送（必须由用户继承实现）"""
        # 对于无需做细粒度委托控制的策略，可以忽略onOrder
        pass
    
    #----------------------------------------------------------------------
    def onTrade(self, trade):
        """收到成交推送（必须由用户继承实现）"""
        # 对于无需做细粒度委托控制的策略，可以忽略onOrder
        pass
    
    def outputSignal(self):
        for con in self.condictions:
            print con.getSignalStr()
